#ifndef RENDERER_H
#define RENDERER_H

#include "../Config/Export.h"
#include "../Utilities/Singleton.h"
#include "../Utilities/TColor4.h"
#include "../Utilities/TColor3.h"
#include "../Maths/TVector3.h"
#include "../Core/Texture.h"
#include "../Core/IBufferBase.h"
#include "../Core/Shader.h"

namespace epix {

class SHARED Renderer : public Singleton<Renderer>
{
    MAKE_SINGLETON(Renderer)

    public:

        ///Parameters
        void init(float near = 0.1f, float far = 100000.f, int fov = 75, Color3i bgColor = Color3i(255, 255, 255), int swapInterval = 1);
        void resize(int width, int height);

        bool initExtensions();
        bool checkExtension(const char *name);

        float getNear() const;
        float getFar() const;
        int getFov() const;

        Vector2i getSize() const;
        Color3i getBgColor() const;

        void set2DMode();
        void end2DMode();

        void setPolygonMode(GLenum face = GL_FRONT_AND_BACK, GLenum mode = GL_FILL);

        ///Scene
        void lookAt(Vector3d cam, Vector3d target = Vector3d(0, 0, 0), Vector3d axes = Vector3d(0, 0, 1));
        void beginScene(Color4f color = Color4f());
        void endScene();

        ///Matrix
        void setMatrix(GLenum mode);
        void pushMatrix();
        void popMatrix();

        ///Transformations
        void scale(const Vector3d &scale);
        void translate(const Vector3d &pos);
        void rotate(GLdouble angle, const Vector3d &rot);

        ///Buffers
        void setVertexBuffer(IBufferBase *buffer);
        void setIndexBuffer(IBufferBase *buffer);
        void drawPrimitives(GLenum mode, GLsizei count, GLint first = 0);
        void drawIndexedPrimitives(GLenum mode, unsigned int count, unsigned int first = 0);

        ///Textures
        void setTexture(Texture *texture);
        void setMultiTexture(Texture *texture, int unit = 0);

        ///Shader
        void setShader(Shader *shader);
		Shader *getShader() const;

    private:

        Vector2i _size;
        float _near, _far;
        Color3i _bgColor;
        int _fov;

        IBufferBase *_indexBuffer;
		Shader *_activeShader;

        double _fps, _current_time, _start_time;
};

}
#endif
